package snafu.framework.senses;

import java.util.HashSet;
import java.util.Set;

import snafu.framework.senses.perceptions.Perception;
import snafu.framework.senses.perceptions.PerceptionItself;
import snafu.framework.senses.stimuli.Stimulus;
import snafu.framework.view.Access;
import snafu.framework.view.ViewFactory;

public class SenseItself implements ViewFactory<SenseView>, Sense{

	protected Set<PerceptionItself> percetableStimuli;

	public SenseItself() {
		percetableStimuli = new HashSet<PerceptionItself>();
	}
	
	public SenseItself(PerceptionItself perception) {
		this();
		addPerception(perception);
	}
	
	public SenseItself(Set<PerceptionItself> perceptions) {
		this();
		addPerceptions(perceptions);
	}
	
	public SenseItself(Class<? extends Stimulus> stimulus, int minStrength, int maxStrength) {
		this(new PerceptionItself(stimulus, minStrength, maxStrength));
	}
	
	public void addPerception(PerceptionItself perception) {
		percetableStimuli.add(perception);
	}
	
	public void addPerceptions(Set<PerceptionItself> perceptions) {
		percetableStimuli.addAll(perceptions);
	}
	
	@Override
	public Set<Perception> getPerceptableStimuli() {
		Set<Perception> newStimuli = new HashSet<Perception>();
		if (percetableStimuli == null) {
			return newStimuli;
		}
		
		for (Perception perception : percetableStimuli) {
			newStimuli.add(perception);
		}
		
		return newStimuli;
	}

	@Override
	public boolean canPercept(Stimulus stimulus) {
		
		for (Perception perception : percetableStimuli) {
			// the stimulus and the stimulus the sense can percept have the same class
			boolean sameClass = perception.getStimulus().isAssignableFrom(stimulus.getClass());
			// the stimulus is in range of the perception
			boolean inRange = perception.getStrength().crosses(stimulus.getStrength());
			
			if (sameClass && inRange) {
				return true;
			}
		}
		return false;
	}

	@Override
	public SenseView createView(Access access) {
		return new SenseView(access, this);
	}

}
